#ifndef _WND_WIDGET_H_
#define _WND_WIDGET_H_

#include "wnd_api.h"


#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */


#define CTRL_PATH			"share/res/png"			//!< 控件图片的总体路径


#define UI_COORD_MIN		0
#define UI_COORD_MAX		7200				//!<虚拟坐标的总大小

#if 0
/* 屏幕和实际的差异*/
#define UI_COORD_X			(UI_COORD_MAX*1)/60
#define UI_COORD_Y			(UI_COORD_MAX*1)/40
#define UI_COORD_WIDTH		0	//(UI_COORD_MAX*1)/20
#define UI_COORD_HEIGHT		0	//(UI_COORD_MAX*1)/20


#define UI_COORD_LEFT
#define UI_COORD_RIGHT
#define UI_COORD_TOP
#define UI_COORD_BOTTOM
#endif

/**
 * @brief 颜色
 */
typedef enum ui_color_e {
	UI_COLOR_DEFAULT_E = 0,	//!<	默认
	UI_COLOR_PARENT_E,		//!<	父窗口风格
    UI_COLOR_BLACK_E ,   	//!<	黑色
    UI_COLOR_LIGHTWHITE_E,  //!<	白色
    UI_COLOR_CYAN_E,        //!<	蓝绿色
    UI_COLOR_MAGENTA_E,     //!<	洋红色
    UI_COLOR_BLUE_E,        //!<	蓝色
    UI_COLOR_YELLOW_E,      //!<	黄色
    UI_COLOR_GREEN_E,       //!<	绿色
    UI_COLOR_RED_E,         //!<	红色
    UI_COLOR_DARGRAY_E,     //!<	深灰
    UI_COLOR_LIGHTGRAY_E,   //!<	浅灰
    UI_COLOR_DARKCYAN_E,    //!<	深青
    UI_COLOR_DARKMAGENTA_E, //!<	深洋红
    UI_COLOR_DARKBLUE_E,    //!<	深蓝
    UI_COLOR_DARKYELLOW_E,  //!<	深黄
    UI_COLOR_DARKGREEN_E,   //!<	深绿
    UI_COLOR_DARKRED_E,     //!<	深红
    UI_COLOR_TRANSPARENT_E, //!<	透明
    UI_COLOR_INVALID_E,     //!<	无效
    UI_COLOR_ORANGE_E,      //!<	橙色
}UI_COLOUR_E;




















struct wnd_widget_s;

/**
 * @brief 主窗口私有属性
 */
typedef struct wnd_widget_main_s {
    pthread_t stPid; //!<	主窗口的线程id	，不需要自己填充
    sem_t stWait;    //!<	主窗口的信号量	，不需要自己填充
} WND_WIDGET_MAIN_S;


/**
 * @brief 按钮的私有属性
 */
typedef struct wnd_widget_button_s {
	bool bMultLine; 				//!<	是否显示多行 true显示多行 false 显示单行 对应风格 BS_MULTLINE
	bool bCursel;					//!<	当前是否被选中 不需要手动填充
	UI_COLOUR_E enCurselBkColor;	//!<	选中时候的背景颜色
	UI_COLOUR_E enCurselFontColor;	//!<	选中时候的字体颜色
} WND_WIDGET_BUTTON_S;


/**
 * @brief 图标按钮的私有属性
 */
typedef struct widget_picture_button_s {
	int s32RealSizeImage;	//!<	图片的缩放 0.图片充满整个按钮 1.图片原始比例
	BITMAP stBitMap;		//!<	存放下载的图片消息 不需要手动填充
	char s8MapPath[125];	//!<	存放图片的路径 需要手动填充
} WIDGET_PICTURE_BUTTON_S;

/**
 * @brief 复选按钮私有属性
 */
typedef struct widget_multi_button_s {

	/**
	 * @brief 是否自动发送消息来设定标记 （一般选择1 3）
	 *		0. 应用程序字节发送消息来设定选中标记
	 *		1.控件会自动在选中和非选中状态之间切换
	 *		2.不显示第三种状态, 且应用程序字节发送消息来设定选中标记
	 *		3.显示第三种状态， 且控件会自动在选中和非选中状态之间切换
	 *		是否显示第三种状态——复选框内是灰色的，这种状态表明该复选框不能被选择或者禁止使用
	 */
	int s32AutoCheck;
	/**
	 * @brief 字符串显示在那边 0.右边 1.左边
	 * 		另外还有一些风格可用于复选框字体 ，可在注册全局结构体是赋值 u64Style
	 *		设置 BS_LEFT、 BS_CENTER、 BS_RIGHT、 BS_TOP、 BS_VCENTER、 BS_BOTTOM
	 *
	 */
	int s32LeftText;
} WIDGET_MULTI_BUTTON_S;

/**
 * @brief 单选按钮的私有属性
 */
typedef struct widget_radio_button_s {
	/**
	 * @brief 是否自动发送消息来设定标记 （一般选择1 3）
	 *			0. 应用程序字节发送消息来设定选中标记
	 *			1.控件会自动在选中和非选中状态之间切换
	 */
	int s32AutoCheck;
	/**
	 * @brief 字符串显示在那边 0.右边 1.左边
	 *			另外还有一些风格可用于单选框字体 ，可在注册全局结构体时赋值 u64Style
	 *			设置BS_LEFT、 BS_CENTER、 BS_RIGHT、 BS_TOP、 BS_VCENTER、 BS_BOTTOM
	 *
	 */
	int s32LeftText;
	/**
	 * @brief  单选按钮通常成组使用，同一组单选按钮每一刻只能有一个被选中。在创建一组单选按钮时，
	 *			我们需要设定它们的状态是互斥的，因此，要在创建第一个单选按钮时使用 WS_GROUP 风格，
	 *			以将其设置为该组单选按钮的“打头按钮”
	 *			0.常规单选按钮 1.单选按钮组
	 */
	int s32GroupSta;
	/**
	 * @brief 是否以普通按钮的形式出现 0.以单选按钮的形式出现 1.以常规的方形按钮的形式出现
	 */
	int s32PushLike;
} WIDGET_RADIO_BUTTON_S;

/**
 * @brief 静态图片显示的私有属性
 */
typedef struct wnd_widget_picture_s {
	bool bNotify;			//!<	是否需要产生通知吗 意思是鼠标点击后会不会发消息到回调函数 0.不会 1.会
	BITMAP stBitMap;		//!<	存放下载的图片消息 不需要手动填充
	char s8MapPath[125];	//!<	存放图片的路径 需要手动填充
} WND_WIDGET_STATIC_PICTURE_S;

/**
 * @brief 双图片按钮的私有属性
 */
typedef struct wnd_widget_double_picture_button_s {
	//bool bNotify;					//!<	 是否需要产生通知吗 意思是鼠标点击后会不会发消息到回调函数 0.不会 1.会

	char s8MapPath[125];			//!<	存放图片的路径 需要手动填充
	char s8MapPathCursel[125];		//!<	存放点击按钮后存放的图片的路径 需要手动填充
	BITMAP stBitMap;				//!<	存放下载的图片消息 不需要手动填充
	BITMAP stBitMapCursel;			//!<	存放下载的图片消息 不需要手动填充
	bool bCursel;					//!<	是否为已经点击的状态 0.没有点击 1.已经点击了
	unsigned int u32WndIdCursel;	//!<	当前被选中时候显示的图片的窗口id，不需要自己填充
} WND_WIDGET_DOUBLE_PICTURE_BUTTONS;


/**
 * @brief 下拉菜单的条目属性
 */
typedef struct widget_drop_down_itm_s {
	char ps8Name[64];				//!<	 下拉菜单的条目名称指针，需要手动填充，没有不填
} WIDGET_DROP_DOWN_ITM_S;



/**
 * @brief 下拉列表的私有属性
 */
typedef struct wnd_widget_drop_down_s {
	WIDGET_DROP_DOWN_ITM_S *pstItm;	//!<	条目内容的指针
	int s32Num;						//!<	条目内容的数量
	int s32ListHeight;				//!<	列表框的高度
} WND_WIDGET_DROP_DOWN_S;


/**
 * @brief 编辑框
 */
typedef struct wnd_widget_edit_s {
	unsigned int u32Type;				//!<	编辑框的类型 0.单行编辑框 1.多行编辑框 2.单行双向文本编辑框
} WND_WIDGET_EDIT_S;

/**
 * @brief 列表菜单的私有属性
 */
typedef struct wnd_widget_list_menu_s {
	/**
	 * @brief 子控件排列方式 手动填
	 *		1.完全按照坐标排列
	 *		2.按照 u32Ctrlheight 的高度排列
	 */
	int s32ChildArray;

	unsigned int u32Ctrlheight;		//!<	列表里面的的部件的高度
	int s32Left;					//!<	左 端空隙的距离 s32ChildArray为2时有效
	int s32Right;					//!<	右 端空隙的距离 s32ChildArray为2时有效
	int s32Top;						//!<	上 端空隙的距离 s32ChildArray为2时有效
	int s32Bottom;					//!<	下 端空隙的距离 s32ChildArray为2时有效
	CTRLDATA *pstMenuList;			//!<	子控件指针 自动填
	int s32MenuListNum;				//!<	子控件个数 自动填


} WND_WIDGET_LIST_MENU_S;

/**
 * @brief 菜单的条目
 */
typedef struct widget_menu_itm_s {
	char ps8ItmName[64];				//!<	下拉菜单的条目名称指针，需要手动填充，没有不填
} WIDGET_MENU_ITM_S;

/**
 * @brief 属性列页的私有属性
 */
typedef struct wnd_widget_attr_page_s {
	DLGTEMPLATE stAttrPage;			//!<	属性页
	int s32AttrPageNum;				//!<	属性页的数量
	WIDGET_MENU_ITM_S *pstItm;		//!<	下拉菜单的条目名称指针，需要手动填充，没有不填
	int s32ItmNum;					//!<	下拉菜单条目数量
	int s32Index;					//!< 	索引
} WND_WIDGET_ATTR_PAGE_S;



/**
 * @brief 对话框的私有属性
 */
typedef struct wnd_widget_dlg_s {
	DLGTEMPLATE stDlgInfo;			//!<	对话框结构体 不需要手动填充
} WND_WIDGET_DLG_S;

/**
 * @brief 图标控件
 */
typedef struct wnd_widget_icon_view_s {
	char s8IconPath[128];			//!<	下载图片的路径 需要手动填写
	char s8Name[64];				//!<	图标按钮下方的名字，不显示名字则不填
	IVITEMINFO stIconItem;			//!<	添加图标按钮时用的临时结构体，不需要手动填充
	BITMAP stIconMenu;				//!<	图片消息下载到这个结构体里面，不用手动填写
	BITMAP stIconMenuCursel;		//!<	图片消息下载到这个结构体里面，不用手动填写
	char s8IconPathCursel[128];		//!<	选中时显示的图片的路径 需要手动填写
	bool bCursel;					//!<	当前是否被选中，不用手动填写
	UI_COLOUR_E enFontColorCursel;	//!<	选中时候显示的字体颜色
} WND_WIDGET_ICON_VIEW_S;



/*!
 * 控件集合 控件会在一定的空间内按照比例排列
 *
 */
typedef struct wnd_widget_ctrl_sets_s {
	int s32Direction;				//!<	控件排列的方向 0.横向 1.纵向 2.填满一个区域
	int s32Left;					//!<	左 端空隙的距离
	int s32Right;					//!<	右 端空隙的距离
	int s32Top;						//!<	上 端空隙的距离
	int s32Bottom;					//!<	下 端空隙的距离
	bool bVScroll;					//!<	是否开启水平滚动条 false.不开启 true.开启
	bool bHScroll;					//!<	是否开启垂直滚动条 false.不开启 true.开启
	int s32Height;					//!<	控件的高， s32Direction 为3的时候有效
} WND_WIDGET_CTRL_SETS_S;



/**
 * @brief 可以创建的部件的类型
 */
typedef enum wnd_widget_type_e {
    WND_WIDGET_TYPE_MAIN_E = 1,       	//!<	创建主窗口
    WND_WIDGET_TYPE_BUTTON_E,         	//!<	创建一个按钮
    WND_WIDGET_TYPE_PICTURE_BUTTON_E, 	//!<	创建一个图标按钮
    WND_WIDGET_TYPE_MULTI_BUTTON_E,   	//!<	创建一个复选按钮
    WND_WIDGET_TYPE_RADIO_BUTTON_E,   	//!<	创建一个单选按钮
    WND_WIDGET_TYPE_STATIC_PICTURE_E, 	//!<	创建一个静态图片显示
    WND_WIDGET_TYPE_STATIC_TEXT_E,   	//!<	创建一个字体显示静态框
    WND_WIDGET_TYPE_SCROLL_E,         	//!<	创建一个滚动条列表
    WND_WIDGET_TYPE_ATTR_LIST_E,      	//!<	创建一个属性页列表
    WND_WIDGET_TYPE_ATTR_PAGE_E,      	//!<	创建一个属性页，(属性列表的从属分页，创建属性列表后再创建其分页的时候用到，不能单独使用)
    WND_WIDGET_TYPE_EDIT_E,          	//!<	创建一个编辑框
    WND_WIDGET_TYPE_MENU_BUTTON_E,    	//!<	创建一个菜单按钮,(暂时没有实现)
	WND_WIDGET_TYPE_DROP_DOWN_E,      	//!<	创建一个下拉列表
	WND_WIDGET_TYPE_DLG_E,    		  	//!<	对话框
	WND_WIDGET_TYPE_ICON_VIEW_E,      	//!<	图标控件,(有缺陷，用双图标按钮或者图片显示代替)
	WND_WIDGET_TYPE_CTRL_SETS_E,      	//!<	控件集合
	WND_WIDGET_TYPE_LAYOUT_E,     	 	//!<	创建一个画布 可以在上面创建子控件
	WND_WIDGET_TYPE_DOUBLE_PIC_BUTT_E,	//!<	创建一个双图片按钮

}WND_WIDGET_TYPE_E;



/**
 * @brief 部件的id
 */
typedef enum wnd_widget_id_e {
    WIDGET_ID_POWER_ON_MODE_E = 1000, //!<开机方式



	/**
	 * @brief 主窗口
	 */
	WIDGET_ID_MAIN_TIME_E,	//!<	时间显示

}WND_WIDGET_ID_E;


/**
 * @brief 部件的分组编号
 */
typedef enum wnd_widget_grop_e {


	/**
	 * @brief 主窗口
	 */
    WIDGET_GRP_MAIN_MENU_E  = 1000,		//!<	菜单
	WIDGET_GRP_MAIN_MOUSE_E,			//!<	鼠标
}WND_WIDGET_GROP_E;


/**
 * @brief 部件的私有属性
 */
typedef union wnd_widget_attr_u {

	WND_WIDGET_MAIN_S stMain;							//!< 	主窗口
	WND_WIDGET_BUTTON_S stButton;						//!< 	普通按钮
	WIDGET_PICTURE_BUTTON_S stPictureButton;			//!< 	图片按钮
	WIDGET_MULTI_BUTTON_S stMultiButton;				//!< 	复选按钮
	WIDGET_RADIO_BUTTON_S stRadioButton;				//!< 	单选框按钮
	WND_WIDGET_STATIC_PICTURE_S stStaticPicture;		//!< 	静态显示图片
	WND_WIDGET_LIST_MENU_S stListMenu;					//!< 	列表菜单
	WND_WIDGET_ATTR_PAGE_S stAttrPage;					//!< 	属性页
	WND_WIDGET_DLG_S stDlg;								//!< 	对话框
	WND_WIDGET_ICON_VIEW_S stIconView;					//!< 	图标控件
	WND_WIDGET_CTRL_SETS_S stCtrlSets;					//!< 	控件集合
	WND_WIDGET_DOUBLE_PICTURE_BUTTONS stDouPicButt;		//!< 	双图片按钮 点击后会显示另一个图片的按钮
	WND_WIDGET_DROP_DOWN_S stDropDown;					//!< 	下拉框
	WND_WIDGET_EDIT_S stEdit;							//!< 	编辑框
}WND_WIDGET_ATTR_U;





/**
 * @brief 字体的风格
 */
typedef struct wnd_widget_font_s {
	int s32FontSize;			//!< 	字体大小 0.默认大小， -1.跟随父窗口的大小
	UI_COLOUR_E enFontColor;	//!<	字体的颜色
	LOGFONT *pstFont;		 	//!<	默认窗口字体结构体 自动填充
}WND_WIDGET_FONT_S;

/**
 * @brief 部件的属性
 */
typedef struct wnd_attr_s {
    char s8Name[64];             //!<	部件的名字，当要显示汉字的时候会显示这个数组的内容
    unsigned int u32Group;       //!<	部件的分组id，当要对一组部件进行操作的时候有效
    unsigned int u32WndId;       //!<	部件的窗口id，不需要手动填充
    unsigned int u32ParentWndId; //!<	部件的父部件窗口id，指出需要在哪个部件上面创建新部件,创建窗口的时候传入
    unsigned long u64Style;      //!<	部件的风格，可以填，也可以不填
    unsigned long u64ExStyle;    //!<	部件的带外风格，只对主窗口有效果，可以不填，也可以填
    unsigned int u32Id;          //!<	部件的id，未创建部件前的唯一标识，建议全局唯一
    unsigned int u32WndX;        //!<	部件的x坐标，虚拟坐标
    unsigned int u32WndY;        //!<	部件的y坐标，虚拟坐标
    unsigned int u32WndWidth;    //!<	部件的宽度，虚拟宽度
    unsigned int u32WndHeight;   //!<	部件的高度，虚拟高度
    UI_COLOUR_E enBkColor;       //!<	背景颜色
    bool bShowNow;               //!<	是否立即显示部件 ture。显示 false。不显示
    bool bBorder;                //!<	是否显示边界 ture。显示 false。不显示
    bool bCaption;               //!<	是否显示标题 false.不显示 true.
    WND_WIDGET_FONT_S stFont;    //!<	部件的字体风格
    //pthread_t stDestroyPid;      //!<
    //bool bDestroy;               //!<
}WND_ATTR_S;



/**
 * @brief 部件的回调函数
 */
typedef union wnd_fops_s {
	/**
	 * @brief 回调函数
	 */
    int (*CallBack)(HWND u32Wnd, int s32Message, WPARAM u32Param, LPARAM u64Param);
	/**
	 * @brief 回调函数，不需要填，因为minigui有的回调函数返回值不一样，所以用这个作转换
	 */
    void (*CallBackByVoid)(HWND u32Wnd, int s32Message, int u32Param, DWORD u64Param);
}WND_FOPS_S;

/**
 * @brief 部件的状态
 */
typedef struct wnd_sta_s {
    bool bCreate; //!<	窗口部件是否被创建 true.被创建了 false.没有被创建
    bool bShow;   //!<	窗口部件是否被显示 true.被显示了 false.没有被显示 (暂时没有用到)
}WND_STA_S;




/**
 * @brief 部件的公共属性
 */
typedef struct widget_commom_s {
    WND_ATTR_S stAttr; //!< 窗口部件的属性
    WND_FOPS_S stFops; //!< 窗口部件的回调函数
    WND_STA_S stSta;   //!< 窗口部件的状态
} WIDGET_COMMON_S;

/**
 * @brief 部件结构体
 */
typedef struct wnd_widget_s {
    WND_WIDGET_TYPE_E enType;       //!< 窗口部件的类型
    WND_WIDGET_ATTR_U unPrivate;    //!< 窗口部件的私有属性
    WIDGET_COMMON_S stCommon;       //!< 窗口部件的公共属性
    struct wnd_widget_s *pstWidget; //!< 窗口部件的子部件指针
    int s32WidgetNum;               //!< 窗口部件子部件的数量
} WND_WIDGET_S;

/*
typedef struct wnd_widget_handle_s {
	struct wnd_widget_s *pstWidget;
	int s32WidgetNum;
} WND_WIDGET_HANDLE_S;
*/



/*!
 * 创建一个部件
 * @return  返回创建的部件的窗口id
 * @param pstWnd 要创建的部件的句柄
 * @param u32Parent 父窗口id，指出需要创建在哪个窗口上面
 * @see
 */
extern unsigned int WND_WIDGET_Create(WND_WIDGET_S *pstWnd, unsigned int u32Parent);

/*!
 * 按照组编号创建一组部件
 * @return 0.成功 -1.失败
 * @param pstWnd 部件句柄 本接口会搜索这个句柄下的所有子部件，找到所有符合的组编号并创建
 * @param u32Group 窗口组编号
 * @param u32ParentWnd 父窗口id，指出窗口创建在哪个父窗口
 * @see
 */
extern int WND_WIDGET_CreateChildByGroup(WND_WIDGET_S *pstWnd, unsigned int u32ParentWnd, unsigned int u32Group);

/*!
 * 销毁一个部件，会销毁部件下的所有子部件
 * @param pstWnd 要销毁的部件的句柄
 * @see
 */
extern void WND_WIDGET_Destroy(WND_WIDGET_S *pstWnd);


/*!
 * 初始化字体
 * @return  返回初始化后的字体
 * @param pstFont 要初始化的字体
 * @see
 */
extern LOGFONT * WND_WIDGET_InitFont(WND_WIDGET_FONT_S *pstFont);

/*!
 * 销毁字体
 * @param pstFont 要销毁的字体
 * @see
 */
extern void WND_WIDGET_DeInitFont(WND_WIDGET_FONT_S *pstFont);

/*!
 * 刷新同一组下面的图标按钮的当前高亮选项
 * @param pstParentWnd 同一组图标控件的父窗口句柄
 * @param u32Wnd 当前需要被点亮图标控件的图标控件的窗口id
 * @see
 */
extern int WND_WIDGET_FlushIconCursel(WND_WIDGET_S *pstParentWnd, unsigned int u32Wnd);

/*!
 * 刷新一个窗口的同一个组窗口的选中高亮
 * @return 0.成功 -1.失败
 * @param u32Wnd 要刷新的窗口
 * @see
 */
extern int WND_WIDGET_FlushIconCtrlSetsCursel(unsigned int u32Wnd);

/*!
 * 创建一个部件
 * @return  返回创建的部件的窗口id
 * @param pstWnd 部件的句柄
 * @param u32Parent 父窗口id，指出需要在哪个窗口上面创建
 * @param u32WndHeight 部件的真实高
 * @param u32WndWidth 部件的真实宽
 * @param u32WndX 部件的真实x坐标
 * @param u32WndY 部件的真实y坐标
 * @see
 */
extern unsigned int WND_WIDGET_CreateSwitch(WND_WIDGET_S *pstWnd,
									unsigned int u32Parent,
									unsigned int u32WndX,
									unsigned int u32WndY,
									unsigned int u32WndWidth,
									unsigned int u32WndHeight);

/*!
 * 切换双图片按钮的高亮
 * @param u32Wnd 要切换的双图片按钮窗口id
 * @see
 */
extern int WND_WIDGET_DoublePictureButtonShow(unsigned int u32Wnd);

/*!
 * 刷新一个双图片按钮的当前显示图片
 * @return  0.成功 -1 失败
 * @param u32Wnd 要刷新的双图片按钮的窗口id
 * @see
 */
extern int WND_WIDGET_FlushDoublePictureButtonCursel(unsigned int u32Wnd);

/*!
 * 属性当前按钮的高亮，只对在同一个子部件下的按钮有效果
 * @return  0.成功 -1.失败
 * @param u32Wnd 要刷新的按钮窗口id
 * @see
 */
extern int WND_WIDGET_FlushButtonCursel(unsigned int u32Wnd);

/*!
 * 按照编号创建部件
 * @return 返回创建的窗口id
 * @param pstWnd 部件句柄 本接口会搜索这个句柄下的所有子部件，直到找到符合的id并创建
 * @param u32Id 要创建的部件的编号
 * @param u32ParentWnd 父窗口id，指出窗口创建在哪个父窗口
 * @see
 */
extern unsigned int WND_WIDGET_CreateById(WND_WIDGET_S *pstWnd, unsigned int u32ParentWnd, unsigned int u32Id);

/*!
 * 按照编号销毁部件
 * @param pstWnd 部件句柄 本接口会搜索这个句柄下的所有子部件，直到找到符合的id并销毁
 * @param u32Id 要创建的部件的编号
 * @see
 */
extern void WND_WIDGET_DestroyById(WND_WIDGET_S *pstWnd, unsigned int u32Id);


/*!
 * 将部件的风格有效化
 * @param pstWnd
 * @see
 */
extern void WND_WIDGET_EnbleStly(WND_WIDGET_S *pstWnd);



#ifdef __cplusplus
}
#endif  /* __cplusplus */

#endif
